package com.yungu.swift.socket.communication.service.impl;


import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.yungu.swift.autoconfig.redis.RedisCacheService;
import com.yungu.swift.base.ResponseData;
import com.yungu.swift.lbs.service.LocationService;
import com.yungu.swift.order.model.dto.OrderDto;
import com.yungu.swift.order.model.param.ApiOrderUuidParam;
import com.yungu.swift.order.model.vo.OrderEstimateVo;
import com.yungu.swift.order.service.OrderFareService;
import com.yungu.swift.order.service.OrderService;
import com.yungu.swift.socket.communication.message.UploadLocationJsonMessage;
import com.yungu.swift.socket.communication.message.UploadLocationMessage;
import com.yungu.swift.socket.communication.service.UploadLocationService;
import com.yungu.swift.utils.JsonUtils;
import com.yungu.swift.utils.MapUtils;
import com.yungu.swift.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * @author cuixiuyin
 * @date 2018/12/14
 */
@Service
public class UploadLocationServiceImpl implements UploadLocationService {

    @Reference
    private LocationService locationService;
    @Reference
    private OrderService orderService;
    @Reference
    private OrderFareService orderFareService;
    @Autowired
    private RedisCacheService cacheService;


    @Override
    public ResponseData<Map<String, Object>> uploadDriverLocation(UploadLocationMessage uploadLocationMessage) {
        Map<String, Object> calculateMap = calculatePosition(uploadLocationMessage);
        //如果订单未创建，订单id为空，点依然要传
        ResponseData<Boolean> responseData = locationService.uploadDriverLocation(calculateMap);
        if (!responseData.isSuccess() || responseData.getData() == null || responseData.getData().equals(Boolean.FALSE)) {
            return ResponseData.buildErrorResponse(ResponseData.ERROR_CODE, "", MapUtils.build());
        }

        //放入缓存，作为每个司机最后保存时间，方便定时扫描
        //如果有订单就更新订单缓存
        String mainOrderUuid = StringUtils.isEmpty(uploadLocationMessage.getMainOrderUuid()) ? "" : uploadLocationMessage.getMainOrderUuid();
        String orderUuid = StringUtils.isEmpty(uploadLocationMessage.getOrderUuid()) ? mainOrderUuid : uploadLocationMessage.getOrderUuid();

        cacheService.set("hasOrder" + uploadLocationMessage.getDriverUuid(), orderUuid, false);
        cacheService.set("driverUpload" + uploadLocationMessage.getDriverUuid(), new Date(), false);
        cacheService.set("driverCurrentLng" + uploadLocationMessage.getDriverUuid(), uploadLocationMessage.getLng(), false);
        cacheService.set("driverCurrentLat" + uploadLocationMessage.getDriverUuid(), uploadLocationMessage.getLat(), false);

        return ResponseData.buildSuccessResponse("更新司机位置信息成功", MapUtils.build("totalFare", calculateMap.get("totalFare")));
    }

    @Override
    public ResponseData<String[]> uploadDriverLocations(UploadLocationJsonMessage uploadLocationJsonMessage) {
        try {
            ArrayNode jsonArray = JsonUtils.readArray(uploadLocationJsonMessage.getLocationJson());
            String[] successPointUuids = new String[jsonArray.size()];
            int j = 0;
            for (int i = 0, len = jsonArray.size(); i < len; i++) {
                UploadLocationMessage clientPoint = JsonUtils.readValue(jsonArray.get(i).asText(), UploadLocationMessage.class);
                Date date = new Date(clientPoint.getUploadTime());
                ResponseData<Boolean> responseData = locationService.uploadDriverLocation(clientPoint.getDriverUuid(),
                        clientPoint.getDriverType(),
                        clientPoint.getLng(),
                        clientPoint.getLat(),
                        clientPoint.getDistance(),
                        date,
                        clientPoint.getOrderUuid(),
                        clientPoint.getAngle(),
                        clientPoint.getAppid(),
                        clientPoint.getOrderStatus(),
                        0D, 0D);
                if (responseData.isSuccess() && responseData.getData() != null) {
                    successPointUuids[j++] = clientPoint.getLocationUuid();
                }
                return ResponseData.buildSuccessResponse("上报位置成功", successPointUuids);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ResponseData.buildSuccessResponse("上报位置成功", null);

    }

    /**
     * 上传点前实时计算总费用
     *
     * @param uploadLocationMessage 位置报文
     * @return Map<String, Object>
     * @author Zerrion
     * @date 2017/12/19
     */
    private Map<String, Object> calculatePosition(UploadLocationMessage uploadLocationMessage) {
        Map<String, Object> map = new HashMap<>(32);

        //实时里程
        Double mileage = Optional.ofNullable(uploadLocationMessage.getMileage()).orElse(0.0);
        Double totalFare = 0D;
        Integer orderStatus = 0;

        if (StringUtils.isNotEmpty(uploadLocationMessage.getOrderUuid())) {
            OrderDto orderDto = orderService.get(uploadLocationMessage.getOrderUuid()).getData();
            if (orderDto != null) {
                orderStatus = orderDto.getSubStatus();
                ApiOrderUuidParam orderUuidParam = new ApiOrderUuidParam();
                orderUuidParam.setOrderUuid(uploadLocationMessage.getOrderUuid());
                ResponseData<OrderEstimateVo> responseData = orderFareService.getRealtimeFare(orderUuidParam);
                if (responseData.isSuccess() && responseData.getData() != null && responseData.getData().getTotalFare() != null) {
                    totalFare = responseData.getData().getTotalFare();
                }
            }
        }

        map.put("driverUuid", uploadLocationMessage.getDriverUuid());
        map.put("driverType", uploadLocationMessage.getDriverType());
        map.put("lng", uploadLocationMessage.getLng());
        map.put("lat", uploadLocationMessage.getLat());
        map.put("distance", uploadLocationMessage.getDistance());
        map.put("orderUuid", uploadLocationMessage.getOrderUuid());
        map.put("angle", uploadLocationMessage.getAngle());
        map.put("appid", uploadLocationMessage.getAppid());
        map.put("orderStatus", orderStatus);
        //key由planMileage改为mileage，表示实际行驶里程，而不是预估
        map.put("mileage", mileage);
        map.put("totalFare", totalFare);
        map.put("areaCode", uploadLocationMessage.getAreaCode());
        map.put("elevation", uploadLocationMessage.getElevation());
        map.put("speed", uploadLocationMessage.getSpeed());
        map.put("bizStatus", uploadLocationMessage.getBizStatus());
        map.put("accuracy", uploadLocationMessage.getAccuracy());
        map.put("positionType", uploadLocationMessage.getPositionType());
        map.put("carModelType", uploadLocationMessage.getCarModelType());
        map.put("appVersion", uploadLocationMessage.getAppVersion());
        map.put("phoneVersion", uploadLocationMessage.getPhoneVersion());
        map.put("mainOrderUuid", StringUtils.stripToEmpty(uploadLocationMessage.getMainOrderUuid()));
        map.put("mainJoinStatus", uploadLocationMessage.getMainJoinStatus());
        map.put("joinStatus", uploadLocationMessage.getJoinStatus());
        return map;
    }

}
